from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, JsonResponse
from apps.users.models import User
import json, re
from django_redis import get_redis_connection
from django.contrib.auth import login, logout, authenticate
from ihome_project.utils.view import LoginRequiredMixin
from ihome_project.libs.qiniuyun.qiniuyun_upload import storage
from django.conf import settings


# Create your views here.


class RealnameAuthenticationView(LoginRequiredMixin, View):
    '''用户实名认证'''

    def post(self, request):
        dict = json.loads(request.body.decode())
        real_name = dict.get('real_name')
        id_card = dict.get('id_card')

        if not all([real_name, id_card]):
            return JsonResponse({'errno': '400',
                                 'errmsg': '缺少必传参数'})

        if not re.match(r'^[\u4E00-\u9FA5]{2,4}$|^[a-zA-Z_-]{5,20}$', real_name):
            return JsonResponse({'errno': '400',
                                 'errmsg': '真实姓名不满足格式要求'})

        if not re.match(r'^\d{17}[\d|x]$', id_card):
            return JsonResponse({'errno': '4004',
                                 'errmsg': '身份证号码不满足格式要求'})

        try:

            request.user.real_name = real_name
            request.user.id_card = id_card
            request.user.save()
        except Exception as e:
            return JsonResponse({'errno': '4001',
                                 'errmsg': '保存数据到数据库失败'})

        return JsonResponse({'errno': '0',
                             'errmsg': '认证信息保存成功'})

    def get(self, request):
        # 判断当前用户是否实名认证
        real_name = request.user.real_name
        id_card = request.user.id_card

        if not all([real_name, id_card]):
            return JsonResponse({'errno': '4002',
                                 'errmsg': '没有实名认证'})

        return JsonResponse({'errno': '0',
                             'data': {'real_name': real_name,
                                      'id_card': id_card},
                             'errmsg': 'ok'})


class ChangeUsernameView(LoginRequiredMixin, View):
    '''修改用户名'''

    def put(self, request):
        # 1 获取参数
        dict = json.loads(request.body.decode())
        name = dict.get('name')

        # 2 校验参数
        if not name:
            return JsonResponse({'errno': 4001, 'errmsg': '缺少必传参数'})
        if not re.match(r'^[\u4E00-\u9FA5]{2,4}$|^[a-zA-Z_-]{5,20}$', name):
            return JsonResponse({'errno': '400',
                                 'errmsg': '用户名不满足格式要求'})
        # 3 保存参数
        try:
            request.user.username = name
            request.user.save()
        except Exception as e:
            return JsonResponse({'errno': 4001, 'errmsg': '保存到数据库失败'})

        return JsonResponse({'errno': '0',
                             'errmsg': '修改成功'
                             })


class AddAvatarView(LoginRequiredMixin, View):
    '''上传头像'''

    def post(self, request):
        # 1.接收参数
        avatar = request.FILES.get('avatar')

        # 2 校验参数
        if not avatar:
            return JsonResponse({'errno': 4002, 'errmsg': '缺少必传参数'})

        # 3 保存到数据库
        file_data = avatar.read()
        result = storage(file_data)
        try:
            request.user.avatar = settings.QNY_HOST + result
            request.user.save()
        except Exception as e:
            return JsonResponse({'errno': 4001, 'errmsg': '保存到数据库失败'})

        dict = {'avatar_url': settings.QNY_HOST + result, }

        return JsonResponse({'errno': 0, 'errmsg': '头像上传成功', 'data': dict})


class InfoView(LoginRequiredMixin, View):
    """个人中心"""

    def get(self, request):
        # 构建数据
        data = {
            'avatar_url': str(request.user.avatar),
            'create_time': request.user.date_joined,
            'mobile': request.user.mobile,
            'name': request.user.username,
            'user_id': request.user.id
        }

        # 返回数据
        return JsonResponse({
            'data': data,
            'errmsg': 'ok',
            'errno': 0
        })


# 废物代码,判断手机号
"""
class MobileCountView(View):
    '''判断手机号是否重复注册'''

    def get(self, request, mobile):
        '''判断手机号是否重复注册'''
        # 1.查询mobile在mysql中的个数
        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'errmsg': '查询数据库出错'})

        # 2.返回结果(json)
        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'count': count})
"""


class RegisterView(View):
    '''用户注册'''

    def post(self, request):
        # 1.接收参数,保存到数据库
        dict = json.loads(request.body.decode())
        mobile = dict.get('mobile')
        phonecode = dict.get('phonecode')
        password = dict.get('password')

        # 2 整体校验
        if not all([mobile, phonecode, password]):
            return JsonResponse({'errno': 4004, 'errmsg': '缺少必传参数'})

        # 3 mobile校验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'errno': 4004,
                                 'errmsg': 'mobile格式有误'})

        # 4 password 校验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'errno': 4004,
                                 'errmsg': 'mobile格式有误'})

        # 5 phonecode校验 (连接数据库)
        redis_conn = get_redis_connection('verify_code')

        # 6 从redis中取值
        sms_code_server = redis_conn.get('sms_%s' % mobile)

        # 7 判断sms_code_server是否存在
        if not sms_code_server:
            return JsonResponse({'errno': 4004,
                                 'errmsg': '短信验证码过期'})

        # 8.把redis中取得值和前端发的值对比
        if phonecode != sms_code_server.decode():
            return JsonResponse({'errno': 4004,
                                 'errmsg': '验证码有误'})

        # 12.保存到数据库 (mobile phonecode password)
        user = User.objects.create_user(username=mobile,
                                        mobile=mobile,
                                        password=password)
        # 实现状态保持
        login(request, user)

        # 13.拼接json返回
        return JsonResponse({'errno': 0, 'errmsg': '注册成功'})


class LoginView(View):

    def post(self, request):
        '''实现登录接口'''
        # 1.接收参数
        dict = json.loads(request.body.decode())

        password = dict.get('password')
        username = dict.get('mobile')
        # 2.校验(整体 + 单个)
        if not all([username, password]):
            return JsonResponse({'errno': '4002',
                                 'errmsg': '缺少必传参数'})

        if re.match(r'^1[3-9]\d{9}$', username):
            User.USERNAME_FIELD = 'mobile'
        else:
            User.USERNAME_FIELD = 'username'

        # 3.验证是否能够登录
        user = authenticate(request=request,
                            username=username,
                            password=password)

        # 判断是否为空,如果为空,返回
        if user is None:
            return JsonResponse({'errno': '4004',
                                 'errmsg': '手机号或者密码错误'})

        # 4.状态保持
        login(request, user)

        # 5.返回json
        response = JsonResponse({'errno': '0', 'errmsg': '登陆成功'})
        response.set_cookie('username', user.username.encode('utf-8').decode('latin-1'),
                            max_age=3600 * 24 * 14)
        return response

    def delete(self, request):
        """实现退出登录逻辑"""

        # 判断是否登录
        if not request.user.is_authenticated:
            # 如果未登录
            return JsonResponse({
                'errno': 4004,
                'errmsg': '未登录'
            })

        # 清理 session
        logout(request)

        # 创建 response 对象.
        response = JsonResponse({'errno': '0',
                                 'errmsg': '已登出'})

        # 调用对象的 delete_cookie 方法, 清除cookie
        response.delete_cookie('username')

        # 返回响应
        return response

    def get(self, request):
        """判断是否登录"""

        if request.user.is_authenticated:

            return JsonResponse({
                "errno": '0',
                "errmsg": "已登录",
                "data": {
                    "name": request.user.username,
                    'user_id': request.user.id
                }})

        else:
            return JsonResponse({
                "errno": '4101',
                "errmsg": '未登录'
            })
